
/**
 *
 */
package com.serviceprovider.business.module.admin.transaction.services.dao.impl;

//~--- non-JDK imports --------------------------------------------------------

import com.serviceprovider.business.module.admin.transaction.model.NewCsvReplica;
import com.serviceprovider.business.module.admin.transaction.services.dao.interfaces.ITransactionImportDataService;
import com.serviceprovider.business.module.admin.transaction.utility.StringUtils;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport;
import org.springframework.stereotype.Repository;

//~--- JDK imports ------------------------------------------------------------

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author mrduongnv@gmail.com
 *
 */
@Repository("transactionImportDataService")
public class TransactioImportDataServiceImpl extends SimpleJdbcDaoSupport implements ITransactionImportDataService {

    /** Logger for this class and subclasses */
    protected final Log logger = LogFactory.getLog(getClass());

    @Autowired
    public TransactioImportDataServiceImpl(@Qualifier("importJdbcTemplate") JdbcTemplate jdbcTemplate) {
        setJdbcTemplate(jdbcTemplate);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void insertTransaction(NewCsvReplica transaction) {
        if (transaction == null) {
            throw new IllegalArgumentException("Transaction object is null");
        }

        if (checkIfTransactionPresent(transaction.getTrace_number())) {
            this.logger.info("Transaction already exists.");

            return;
        }

        String sql = "INSERT INTO newcsvreplica ( historyId, service_provider_id, receiver_name,"
                     + " originator_name, identification_number, orginator_code, transaction_amount, "
                     + "trace_number, extra_field1, extra_field2, extra_field3, extra_field4, extra_field5, processed)"
                     + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

        getJdbcTemplate().update(sql, new Object[] {
            transaction.getHistoryId(), transaction.getService_provider_id(), transaction.getReceiver_name(),
            transaction.getOriginator_name(), transaction.getIdentification_number(), transaction.getOrginator_code(),
            transaction.getTransaction_amount(), transaction.getTrace_number(), transaction.getExtra_filed1(),
            transaction.getExtra_filed2(), transaction.getExtra_filed3(), transaction.getExtra_filed4(),
            transaction.getExtra_filed5(), transaction.isProcessed()
        });
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void updateTransaction(NewCsvReplica transaction) {
        if (transaction == null) {
            throw new IllegalArgumentException("Transaction object is null");
        }

        // final String sql = QueryUtils.buildUpdateSql(transaction,
        // "sp_Target_Transformation");
        // getJdbcTemplate().update(sql);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List retrieveImportedTransactionDataList() {
        String importSql             = "select *  from sp_Target_Transformation";
        List   importtransactionList = getJdbcTemplate().queryForList(importSql);

        if ((importtransactionList == null) || importtransactionList.isEmpty()) {
            return null;
        }

        return importtransactionList;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<NewCsvReplica> retrieveImportedTransactionDataListByHistoryId(Integer fileId) {
        String   importSql = null;
        Object[] objects   = null;

        importSql = "select *  from newcsvreplica where processed =? and historyId=?";
        objects   = new Object[] { Boolean.FALSE, fileId };

        final List importtransactionList = getJdbcTemplate().queryForList(importSql, objects);

        if ((importtransactionList == null) || importtransactionList.isEmpty()) {
            return null;
        }

        List<NewCsvReplica> list              = new ArrayList<NewCsvReplica>();
        Map                 row               = null;
        NewCsvReplica       transactionRecord = null;

        for (Object obj : importtransactionList) {
            row               = (Map) obj;
            transactionRecord = new NewCsvReplica();
            transactionRecord.setId((Integer) row.get("id"));
            transactionRecord.setHistoryId((Integer) row.get("historyId"));
            transactionRecord.setService_provider_id((String) row.get("service_provider_id"));
            transactionRecord.setReceiver_name((String) row.get("receiver_name"));
            transactionRecord.setOriginator_name((String) row.get("originator_name"));
            transactionRecord.setIdentification_number((String) row.get("identification_number"));
            transactionRecord.setOrginator_code((String) row.get("orginator_code"));
            transactionRecord.setTransaction_amount((String) row.get("transaction_amount"));
            transactionRecord.setTrace_number((String) row.get("trace_number"));
            transactionRecord.setExtra_filed1((String) row.get("extra_field1"));
            transactionRecord.setExtra_filed2((String) row.get("extra_field2"));
            transactionRecord.setExtra_filed3((String) row.get("extra_field3"));
            transactionRecord.setExtra_filed4((String) row.get("extra_field4"));
            transactionRecord.setProcessed((Boolean) row.get("processed"));
            list.add(transactionRecord);
        }

        return list;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean checkIfTransactionPresent(String traceNumber) {
        if (!StringUtils.isAllDigits(traceNumber)) {
            return false;
        }

        String sql      = "select trace_number from newcsvreplica where trace_number =" + traceNumber;
        List   dataList = getJdbcTemplate().queryForList(sql);

        return !((dataList == null) || dataList.isEmpty());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public NewCsvReplica retrieveTransactionCSV(String traceNumber) {
        if (StringUtils.isEmpty(traceNumber)) {
            return null;
        }

        String sql      = "select * from sp_Target_Transformation where trace_number =" + traceNumber;
        List   dataList = getJdbcTemplate().queryForList(sql);

        if ((dataList == null) || (dataList.size() != 1)) {
            return null;
        }

        Object        obj               = dataList.get(0);
        Map           row               = (Map) obj;
        NewCsvReplica transactionRecord = new NewCsvReplica();

        transactionRecord.setId(((Integer) row.get("id")));
        transactionRecord.setService_provider_id((String) row.get("receiver_account"));
        transactionRecord.setReceiver_name((String) row.get("receiver_name"));
        transactionRecord.setOriginator_name((String) row.get("originator_name"));
        transactionRecord.setOrginator_code((String) row.get("originator_code"));
        transactionRecord.setTransaction_amount((String) row.get("credit"));
        transactionRecord.setTrace_number((String) row.get("trace_number"));
        transactionRecord.setHistoryId((Integer) row.get("historyId"));
        transactionRecord.setProcessed((Boolean) row.get("processed"));
        transactionRecord.setHistoryId(Integer.valueOf(row.get("file_id").toString()));

        return transactionRecord;
    }

    @Override
    public void insertBatchTransaction(List<NewCsvReplica> records) {
        List<Object[]> batch = new ArrayList<Object[]>();

        // ToDO bulk insert
    }

    @Override
    public ArrayList<String> getAllNonMatchingUserIds() {
        String sql =
            "SELECT distinct(receiver_account) FROM sp_Target_Transformation tr, user us where us.id<>tr.receiver_account";
        Map               row      = null;
        List              list     = getJdbcTemplate().queryForList(sql);
        ArrayList<String> dataList = new ArrayList<String>();

        for (Object obj : list) {
            row = (Map) obj;
            dataList.add((String) row.get("receiver_account"));
        }

        return dataList;
    }

    @Override
    public String[] saveIdMappings(String[] originalIds, String[] importedIds) {
        String[]       newImportedIds = new String[originalIds.length];
        List<Object[]> batch          = new ArrayList<Object[]>();

        for (int i = 0; i < originalIds.length; i++) {
            Object[] values = new Object[2];

            values[0]         = originalIds[i];
            values[1]         = importedIds[i];
            newImportedIds[i] = importedIds[i];
            batch.add(values);
        }

        getSimpleJdbcTemplate().batchUpdate("insert into sp_id_mappings (original_id,mapped_id) values(?,?)", batch);

        return newImportedIds;
    }

    @Override
    public void updateTransactions(String[] originalIds, String[] importedIds) {
        List<Object[]> batch = new ArrayList<Object[]>();

        for (int i = 0; i < originalIds.length; i++) {
            Object[] values = new Object[2];

            values[0] = originalIds[i];
            values[1] = importedIds[i];
            batch.add(values);
        }

        getSimpleJdbcTemplate().batchUpdate(
            "update sp_Target_Transformation set receiver_account=? where receiver_account=?", batch);
    }
}



